Make preload play nice with CSP strict-dynamic Dynamically loaded preloaded scripts were not loaded when a strict-dynamic CSP directive was used. This was because the state regarding whether the element was parser created or not was not properly propoagated to the CSP checks. This CL fixes that and adds tests that make sure that such scripts can be preloaded (and that markup based preloaded scripts with no nonce cannot). Bug: 752922 Change-Id: Ib4f3bce8583ccc9770c261d76167243033e5a112 Reviewed-on: https://chromium-review.googlesource.com/1125064 Reviewed-by: Andy Paicu <andypaicu@chromium.org> Reviewed-by: Mike West <mkwst@chromium.org> Commit-Queue: Yoav Weiss <yoav@yoav.ws> Cr-Commit-Position: refs/heads/master@{#572908} 
diff --git a/preload/preload-strict-dynamic.html b/preload/preload-strict-dynamic.html new file mode 100644 index 0000000..5e473a1 --- /dev/null +++ b/preload/preload-strict-dynamic.html 
@@ -0,0 +1,54 @@ +<!DOCTYPE html> +<head> +<script src="/resources/testharness.js" nonce="123"></script> +<script src="/resources/testharnessreport.js" nonce="123"></script> +<title>CSP strict-dynamic + preload</title> +<meta http-equiv="Content-Security-Policy" content="script-src 'nonce-123' 'strict-dynamic'" /> +</head> +<body> +<link id="static-no-nonce" href="resources/dummy.js?static-no-nonce" rel=preload as=script> +<link id="static-nonce" href="resources/dummy.js?static-nonce" rel=preload as=script nonce="123"> +<script nonce="123"> + let counter = 0; + let cspViolation = false; + let isLoaded = (url) => { + let entries = performance.getEntriesByType("resource"); + for (let entry of entries) { + if (entry.name.indexOf(url) != -1 ) { + return true; + } + } + return false; + } + window.addEventListener("securitypolicyviolation", (e) => { + counter++; + if (e.violatedDirective == "script-src" && e.blockedURI.includes("static-no-nonce")) { + cspViolation = true; + } + }); + let link = document.createElement("link"); + link.rel = "preload"; + link.href = "resources/dummy.js?dynamic-nonce"; + link.as = "script"; + link.onload = () => { ++counter; }; + document.head.appendChild(link); + link = document.getElementById("static-no-nonce"); + link.addEventListener("error", () => { ++counter; }); + link = document.getElementById("static-nonce"); + link.addEventListener("load", () => { ++counter; }); + let t = async_test('preload from nonced script should work with strict-dynamic. preloaded script from markup should not.'); + let timerCounter = 0; + setInterval(t.step_func(() => { + if (counter >= 4 || timerCounter > 5) { + assert_true(isLoaded("dynamic-nonce"), "dynamic inserted preload script should have been loaded"); + assert_true(isLoaded("static-nonce"), "preload tag with a nonce should have been loaded"); + assert_false(isLoaded("static-no-nonce"), "preload tag without a nonce should not have been loaded"); + assert_true(cspViolation, "CSP violation should have fired"); + t.done(); + } + ++timerCounter; + }), 100); + +</script> +</body> +</html>